// // Copyright (c) 2010 All Right Reserved // // vl // // 2010-05-01 // Contains ... namespace LargoCommon.Music { using Abstract; using JetBrains.Annotations; using System; using System.Diagnostics.Contracts; using System.Globalization; using System.IO; using System.Text; using System.Xml.Linq; /// /// Musical Header. /// public class MusicalHeader { #region Fields /// /// Musical metric. /// private MusicalMetric metric; /// /// Musical system. /// private MusicalSystem system; #endregion #region Constructors /// /// Initializes a new instance of the class. /// public MusicalHeader() { this.System = new MusicalSystem(); //// Needed !? (see MidiFileBridge!?) this.Metric = new MusicalMetric(1, 0); this.Tempo = DefaultValue.DefaultTempo; this.Number = 1; this.Origin = DateTime.Now; this.Changed = DateTime.Now; } /// /// Initializes a new instance of the class. /// /// The xml header. public MusicalHeader(XElement xheader) : this() { Contract.Requires(xheader != null); if (xheader == null) { return; } this.Name = XmlSupport.ReadStringAttribute(xheader.Attribute("Name")); this.Number = XmlSupport.ReadIntegerAttribute(xheader.Attribute("Number")); this.FileName = XmlSupport.ReadStringAttribute(xheader.Attribute("FileName")); //// this.FilePath = XmlSupport.ReadStringAttribute(xheader.Attribute("FilePath")); var xorigin = xheader.Attribute("Origin"); this.Origin = xorigin != null ? XmlSupport.ReadDateTimeAttribute(xorigin) : DateTime.Now; var xchanged = xheader.Attribute("Changed"); this.Changed = xorigin != null ? XmlSupport.ReadDateTimeAttribute(xchanged) : DateTime.Now; this.System = new MusicalSystem(xheader.Element("System")); this.Metric = new MusicalMetric(xheader.Element("Metric")); this.Division = XmlSupport.ReadIntegerAttribute(xheader.Attribute("Division")); this.Tempo = XmlSupport.ReadByteAttribute(xheader.Attribute("Tempo")); this.NumberOfBars = XmlSupport.ReadIntegerAttribute(xheader.Attribute("NumberOfBars")); this.NumberOfLines = XmlSupport.ReadIntegerAttribute(xheader.Attribute("NumberOfLines")); this.NumberOfMelodicLines = XmlSupport.ReadByteAttribute(xheader.Attribute("NumberOfMelodicLines")); this.NumberOfRhythmicLines = XmlSupport.ReadByteAttribute(xheader.Attribute("NumberOfRhythmicLines")); } #endregion #region Static Properties /// /// Gets the default musical header. /// public static MusicalHeader GetDefaultMusicalHeader { get { var header = new MusicalHeader { System = new MusicalSystem() { RhythmicOrder = 24, //// 12 HarmonicOrder = DefaultValue.HarmonicOrder }, Metric = new MusicalMetric(4, 2), Division = 240 }; return header; } } #endregion #region Properties - Xml /// /// Gets the get x element. /// /// /// The get x element. /// public XElement GetXElement { get { XElement xheader = new XElement("Header"); xheader.Add(new XAttribute("Name", this.Name ?? string.Empty)); xheader.Add(new XAttribute("Number", this.Number)); xheader.Add(new XAttribute("FileName", this.FileName ?? string.Empty)); //// xheader.Add(new XAttribute("FilePath", this.FilePath ?? string.Empty)); xheader.Add(new XAttribute("Origin", this.Origin ?? DateTime.Now)); xheader.Add(new XAttribute("Changed", this.Changed ?? DateTime.Now)); xheader.Add(this.System.GetXElement); xheader.Add(this.Metric.GetXElement); xheader.Add(new XAttribute("Division", this.Division)); xheader.Add(new XAttribute("Tempo", this.Tempo)); xheader.Add(new XAttribute("NumberOfBars", this.NumberOfBars)); xheader.Add(new XAttribute("NumberOfLines", this.NumberOfLines)); xheader.Add(new XAttribute("NumberOfMelodicLines", this.NumberOfMelodicLines)); xheader.Add(new XAttribute("NumberOfRhythmicLines", this.NumberOfRhythmicLines)); return xheader; } } #endregion #region Properties /* /// /// Gets or sets name of the collection. /// /// Property description. public string FilePath { get; set; } */ /// /// Gets or sets the name of the file. /// /// /// The name of the file. /// public string FileName { get; set; } /// /// Gets or sets the origin. /// /// /// The origin. /// public DateTime? Origin { get; set; } /// /// Gets or sets the changed. /// /// /// The changed. /// public DateTime? Changed { get; set; } /// /// Gets or sets the name. /// /// /// The name. /// public string Name { get; set; } /// /// Gets or sets the number. /// /// /// The number. /// public int Number { get; set; } /// /// Gets the identifier. /// /// /// The identifier. /// public string Identifier => string.Format(CultureInfo.InvariantCulture, "{0}{1}", this.FileName, this.Name.ClearSpecialChars().Trim()); /// /// Gets the name of the two row. /// /// /// The name of the two row. /// [UsedImplicitly] public string TwoRowName => string.Format(CultureInfo.InvariantCulture, "{0}\n{1}", this.FileName, this.NumberName); /// /// Gets the name of the number. /// /// /// The name of the number. /// public string NumberName => string.Format(CultureInfo.InvariantCulture, "\t({0}) {1}", this.Number, this.Name.ClearSpecialChars().Trim()); /// Gets the name of the document file. /// The name of the document file. public string DocumentFileName => string.Format(CultureInfo.InvariantCulture, "{0}_{1}_{2}", this.FileName, this.Number, this.Name.ClearSpecialChars().Trim()); //// public string DocumentFileName => this.FileName; /// /// Gets the rhythmic order. /// /// /// The rhythmic order. /// [UsedImplicitly] public int Timing => this.System.RhythmicOrder / 8; /// /// Gets or sets the metric. /// /// /// The metric. /// public MusicalMetric Metric { get { Contract.Ensures(Contract.Result() != null); if (this.metric == null) { throw new InvalidOperationException("Metric is null."); } return this.metric; } set => this.metric = value ?? throw new ArgumentException("Metric cannot be set null.", nameof(value)); } /// /// Gets or sets the system. /// /// /// The system. /// public MusicalSystem System { get { Contract.Ensures(Contract.Result() != null); if (this.system == null) { throw new InvalidOperationException("System is null."); } return this.system; } set => this.system = value ?? throw new ArgumentException("System cannot be set null.", nameof(value)); } /// /// Gets or sets the division. /// /// /// The division. /// public int Division { get; set; } /// /// Gets or sets tempo. /// /// Property description. public int Tempo { get; set; } /// /// Gets or sets NumberOfBars. /// /// General musical property. public int NumberOfBars { get; set; } /// /// Gets or sets count of loaded parts. /// /// General musical property. /// Returns value. public int NumberOfLines { get; set; } /// /// Gets or sets NumberOfBars. /// /// General musical property. public byte NumberOfMelodicLines { get; set; } /// /// Gets or sets NumberOfBars. /// /// General musical property. public byte NumberOfRhythmicLines { get; set; } #endregion #region String representation /// String representation of the object. /// Returns value. public override string ToString() { var s = new StringBuilder(); s.AppendFormat("Header {0} {1}", this.System, this.Metric); return s.ToString(); } #endregion #region Public methods /// Makes a deep copy of the MusicalHeader object. /// Returns object. public object Clone() { var header = new MusicalHeader { Name = this.Name, Number = this.Number, //// 2019/02 FileName = this.FileName, //// FilePath = this.FilePath, System = this.System, Metric = (MusicalMetric)this.Metric.Clone(), Division = this.Division, Tempo = this.Tempo, NumberOfBars = this.NumberOfBars, NumberOfLines = this.NumberOfLines }; return header; } #endregion } }